/**
 * 认证中间件
 * 验证JWT令牌并将用户信息附加到请求对象
 */

import { verifyToken } from '../utils/jwt.js';

/**
 * 认证中间件
 * 从Authorization header提取JWT令牌，验证后将用户信息附加到req.user
 * 
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 * @param {Function} next - Express next函数
 * @returns {void}
 */
export const authenticate = async (req, res, next) => {
  try {
    // 1. 从header中提取token
    const authHeader = req.headers.authorization || req.headers.Authorization;

    if (!authHeader) {
      return res.status(401).json({
        code: 401,
        error: {
          type: 'NO_TOKEN',
          message: '未提供认证令牌',
        },
      });
    }

    // 2. 验证Bearer格式
    if (!authHeader.startsWith('Bearer ')) {
      return res.status(401).json({
        code: 401,
        error: {
          type: 'INVALID_TOKEN_FORMAT',
          message: '令牌格式错误，应为: Bearer <token>',
        },
      });
    }

    // 3. 提取token
    const token = authHeader.substring(7); // 移除 "Bearer " 前缀

    if (!token || token.trim() === '') {
      return res.status(401).json({
        code: 401,
        error: {
          type: 'NO_TOKEN',
          message: '令牌不能为空',
        },
      });
    }

    // 4. 验证token
    let decoded;
    try {
      decoded = verifyToken(token);
    } catch (error) {
      // 处理token验证错误
      if (error.message === 'TOKEN_EXPIRED') {
        return res.status(401).json({
          code: 401,
          error: {
            type: 'TOKEN_EXPIRED',
            message: '令牌已过期，请重新登录',
          },
        });
      } else if (error.message === 'INVALID_TOKEN') {
        return res.status(401).json({
          code: 401,
          error: {
            type: 'INVALID_TOKEN',
            message: '无效的令牌',
          },
        });
      } else {
        // 其他验证错误
        return res.status(401).json({
          code: 401,
          error: {
            type: 'AUTH_FAILED',
            message: '认证失败',
          },
        });
      }
    }

    // 5. 将用户信息附加到req对象（只附加必要信息）
    req.user = {
      id: decoded.userId || decoded.id,
      username: decoded.username,
      gradeLevel: decoded.gradeLevel,
      role: decoded.role, // 角色信息
    };

    // 6. 继续执行下一个中间件
    next();
  } catch (error) {
    // 捕获任何未预期的错误
    console.error('Authentication middleware error:', error);
    return res.status(500).json({
      code: 500,
      error: {
        type: 'INTERNAL_ERROR',
        message: '服务器内部错误',
      },
    });
  }
};

/**
 * 可选认证中间件
 * 尝试认证，但即使失败也继续执行（用于可选登录的路由）
 * 
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 * @param {Function} next - Express next函数
 * @returns {void}
 */
export const optionalAuthenticate = async (req, res, next) => {
  try {
    const authHeader = req.headers.authorization || req.headers.Authorization;

    // 如果没有token，直接继续（不设置req.user）
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      return next();
    }

    const token = authHeader.substring(7);

    if (!token || token.trim() === '') {
      return next();
    }

    // 尝试验证token
    try {
      const decoded = verifyToken(token);
      req.user = {
        id: decoded.userId || decoded.id,
        username: decoded.username,
        gradeLevel: decoded.gradeLevel,
        role: decoded.role, // 角色信息
      };
    } catch (error) {
      // 验证失败也继续，只是不设置req.user
      // 可以选择记录日志
    }

    next();
  } catch (error) {
    // 任何错误都继续执行
    console.error('Optional authentication middleware error:', error);
    next();
  }
};

/**
 * 角色验证中间件工厂函数
 * 创建一个检查用户角色的中间件
 * 
 * @param {string[]} allowedRoles - 允许的角色列表
 * @returns {Function} Express中间件函数
 */
export const requireRole = (allowedRoles) => {
  return (req, res, next) => {
    // 确保已经过认证
    if (!req.user) {
      return res.status(401).json({
        code: 401,
        error: {
          type: 'UNAUTHORIZED',
          message: '未认证',
        },
      });
    }

    // 检查用户角色
    const userRole = req.user.role || 'user';

    if (!allowedRoles.includes(userRole)) {
      return res.status(403).json({
        code: 403,
        error: {
          type: 'FORBIDDEN',
          message: '权限不足',
        },
      });
    }

    next();
  };
};

/**
 * 年级级别验证中间件工厂函数
 * 创建一个检查用户年级的中间件
 * 
 * @param {string[]} allowedGradeLevels - 允许的年级级别列表
 * @returns {Function} Express中间件函数
 */
export const requireGradeLevel = (allowedGradeLevels) => {
  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({
        code: 401,
        error: {
          type: 'UNAUTHORIZED',
          message: '未认证',
        },
      });
    }

    const userGradeLevel = req.user.gradeLevel;

    if (!allowedGradeLevels.includes(userGradeLevel)) {
      return res.status(403).json({
        code: 403,
        error: {
          type: 'FORBIDDEN',
          message: '该功能不适用于您的年级',
        },
      });
    }

    next();
  };
};

// 默认导出主要的认证中间件
export default authenticate;

